package aor2.components;

import aor2.common.Tracker;
import aor2.components.records.RecordRegister;
import aor2.cpu.ClockCPU;

public class Register implements Element, ElementIO, Cloneable {

	protected long state;
	private Element input;
	private Element output;

	private Tracker history;

	public void in() {
		if (null == input) {
			System.out.println("Registar nije povezan na ulaz");
			return;
		}
		state = input.getState();
	}

	public void out() {
		if (null == output) {
			System.out.println("Registar nije povezan na izlaz");
			return;
		}
		output.setState(state);
	}

	public long getState() {
		return state;
	}

	public void setState(long state) {
		if (this.state != state) {
			this.state = state;
			history.put(new RecordRegister(this));
		}
		this.state = state;
	}

	public Element getInput() {
		return input;
	}

	public void setInput(Element input) {
		this.input = input;
	}

	public Element getOutput() {
		return output;
	}

	public void setOutput(Element output) {
		this.output = output;
	}

	public Register() {
		state = 0;
		input = null;
		output = null;
		history = new Tracker();
		history.put(new RecordRegister(this));
	}

	public Register(long state, Element input, Element output) {
		super();
		this.state = state;
		this.input = input;
		this.output = output;
		if (history == null) {
			history = new Tracker();
			history.put(new RecordRegister(this));
		}
	}

	@Override
	public String toString() {
		return "" + state;
	}

	@Override
	public Register clone() {
		Register registerClone = null;
		try {
			registerClone = (Register) super.clone();

		} catch (Exception e) {
			System.out.println("register cloning error.");
		}
		return registerClone;
	}

	public Tracker getHistory() {
		return history;
	}

	public void previousClk() {
		RecordRegister tmp = (RecordRegister) history.getFromTop(0);
		if (tmp != null) {
			while (((ClockCPU) (tmp).getMark()).compareTo(ClockCPU
					.getInstance()) > 0 && tmp != null) {
				history.takeFromTop();
				tmp = (RecordRegister) history.getFromTop(0);
			}
			if (tmp != null)
				//setState(((RecordRegister) history.takeFromTop()).getValue());
				state = tmp.getValue();
		}
	}

}
